package me.bincker.formwork.web.test

import org.springframework.http.HttpMethod
import org.springframework.http.MediaType
import org.springframework.mock.web.MockHttpSession
import org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.ResultActions
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder
import org.springframework.test.web.servlet.request.MockMultipartHttpServletRequestBuilder
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders
import org.springframework.test.web.servlet.result.MockMvcResultMatchers
import org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder
import org.springframework.test.web.servlet.setup.MockMvcBuilders
import org.springframework.web.context.WebApplicationContext
import java.net.URI

class TestSession(webApplicationContext: WebApplicationContext) {
    val mockMvc: MockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)
            .apply<DefaultMockMvcBuilder>(springSecurity())
            .build()
    private val session: MockHttpSession = MockHttpSession()

    /**
     * 登录
     */
    fun login(username: String = "admin", password: String = "123456"): ResultActions {
        return mockMvc.perform(
                MockMvcRequestBuilders.post("/login")
                        .param("username", username)
                        .param("password", password)
                        .contentType(MediaType.APPLICATION_FORM_URLENCODED)
                        .session(session)
        )
                .andExpect(MockMvcResultMatchers.status().isOk)
    }

    /**
     * 执行请求
     */
    fun perform(requestBuilder: MockHttpServletRequestBuilder) = mockMvc.perform(requestBuilder)

    /**
     * get请求
     */
    operator fun get(urlTemplate: String, vararg uriVars: Any): MockHttpServletRequestBuilder {
        return MockMvcRequestBuilders.get(urlTemplate, *uriVars)
                .session(session)
    }

    /**
     * get请求
     */
    operator fun get(uri: URI): MockHttpServletRequestBuilder {
        return MockMvcRequestBuilders.get(uri)
                .session(session)
    }

    fun post(urlTemplate: String, vararg uriVars: Any): MockHttpServletRequestBuilder {
        return MockMvcRequestBuilders.post(urlTemplate, *uriVars)
                .session(session)
    }

    fun post(uri: URI): MockHttpServletRequestBuilder {
        return MockMvcRequestBuilders.post(uri)
                .session(session)
    }

    fun put(urlTemplate: String, vararg uriVars: Any): MockHttpServletRequestBuilder {
        return MockMvcRequestBuilders.put(urlTemplate, *uriVars)
                .session(session)
    }

    fun put(uri: URI): MockHttpServletRequestBuilder {
        return MockMvcRequestBuilders.put(uri)
                .session(session)
    }

    fun patch(urlTemplate: String, vararg uriVars: Any): MockHttpServletRequestBuilder {
        return MockMvcRequestBuilders.patch(urlTemplate, *uriVars)
                .session(session)
    }

    fun patch(uri: URI): MockHttpServletRequestBuilder {
        return MockMvcRequestBuilders.patch(uri)
                .session(session)
    }

    fun delete(urlTemplate: String, vararg uriVars: Any): MockHttpServletRequestBuilder {
        return MockMvcRequestBuilders.delete(urlTemplate, *uriVars)
                .session(session)
    }

    fun delete(uri: URI): MockHttpServletRequestBuilder {
        return MockMvcRequestBuilders.delete(uri)
                .session(session)
    }

    fun request(method: HttpMethod, urlTemplate: String, vararg uriVars: Any): MockHttpServletRequestBuilder {
        return MockMvcRequestBuilders.request(method, urlTemplate, *uriVars)
                .session(session)
    }

    fun request(httpMethod: HttpMethod, uri: URI): MockHttpServletRequestBuilder {
        return MockMvcRequestBuilders.request(httpMethod, uri)
                .session(session)
    }

    fun request(httpMethod: String, uri: URI): MockHttpServletRequestBuilder {
        return MockMvcRequestBuilders.request(httpMethod, uri)
                .session(session)
    }

    fun multipart(urlTemplate: String, vararg uriVars: Any): MockMultipartHttpServletRequestBuilder {
        return MockMvcRequestBuilders.multipart(urlTemplate, *uriVars)
                .session(session) as MockMultipartHttpServletRequestBuilder
    }

    fun multipart(uri: URI): MockMultipartHttpServletRequestBuilder {
        return MockMvcRequestBuilders.multipart(uri)
                .session(session) as MockMultipartHttpServletRequestBuilder
    }
}